#include "RepairpointBehavior.h"
#include "RepairpointReachedAbilityVisitor.h"
#include "ActivateAbilityVisitor.h"
#include "ActivateStep.h"

RepairpointBehavior::RepairpointBehavior(): activatableObject(0), activatableInterface(0)
{
}

RepairpointBehavior::~RepairpointBehavior()
{
	Clear();
}

void RepairpointBehavior::Clear()
{
	std::list<GameStep*>::iterator it;

	for(it = steps.begin(); it != steps.end(); ++it)
	{
		delete (*it);
	}

	steps.clear();
}

void RepairpointBehavior::SetActivator(GameObject* repairpoint)
{
	ActivateAbilityVisitor activateVisitor;

	repairpoint->Accept(activateVisitor);

	if (activateVisitor.FoundAbility())
	{
		activatableObject = repairpoint;
		activatableInterface = activateVisitor.ActivatableInterface();
	}
}



void RepairpointBehavior::GenerateSteps(Board& board)
{
	Clear();

	if (!activatableObject && !activatableInterface)
		return;

	Cell& cell = board.CellAt(activatableObject);

	const std::list<GameObject*>& cellobjects = cell.GetObjects();
	std::list<GameObject*>::const_iterator it;

	
	for(it = cellobjects.begin(); it != cellobjects.end(); ++it)
	{
		GameObject* object = (*it);

		RepairpointReachedAbilityVisitor repairpointreachedVisitor;

		object->Accept(repairpointreachedVisitor);

		if (repairpointreachedVisitor.FoundAbility())
		{
			AddStep(object, repairpointreachedVisitor.RepairpointReachableInterface());
		}
	}

	if (steps.size())
	{
		ActivateStep* step = new ActivateStep();

		step->SetObject(activatableObject, activatableInterface);
		steps.push_front(step);
	}
}

void RepairpointBehavior::AddStep(GameObject* object, RepairpointReachable* repairpointreachable)
{
	RepairpointStep* step = new RepairpointStep();

	step->SetObject(object, repairpointreachable);

	steps.push_back(step);
}


void RepairpointBehavior::Execute()
{
	std::list<GameStep*>::iterator it;

	for(it = steps.begin(); it != steps.end(); ++it)
	{
		(*it)->Execute();
	}
}


